package net.jcip.examples.chapter6;

import java.util.concurrent.*;

/**
 * CompletionService 源码
 * 这是 `CompletionService` 接口的源代码，它定义了一种服务，用于解耦异步任务的生产和完成任务结果的消费。
 * 以下是接口中定义的方法：
 *
 * - `submit(Callable<V> task)`: 提交一个返回结果的任务，并返回一个表示任务结果的 Future。
 * - `submit(Runnable task, V result)`: 提交一个 Runnable 任务，并返回一个表示任务结果的 Future。
 * - `take()`: 获取并移除下一个完成的任务的 Future，如果没有任务完成则等待。
 * - `poll()`: 获取并移除下一个完成的任务的 Future，如果没有任务完成则返回 null。
 * - `poll(long timeout, TimeUnit unit)`: 获取并移除下一个完成的任务的 Future，如果没有任务完成则等待指定的时间。
 *
 * `CompletionService` 可以用于管理异步 I/O 等场景，其中任务的执行和任务结果的处理是分离的。
 * 通常情况下，`CompletionService` 依赖于一个独立的执行器来实际执行任务，它只管理一个内部的完成队列。
 * `ExecutorCompletionService` 类提供了这种方法的实现。
 */
public class CompletionServiceExample {

    public static void main(String[] args) {
        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);
        // 创建 CompletionService
        CompletionService<Integer> completionService = new ExecutorCompletionService<>(executor);

        // 提交一些任务
        for (int i = 1; i <= 10; i++) {
            final int taskId = i;
            completionService.submit(() -> {
                Thread.sleep((long) (Math.random() * 1000)); // 模拟任务执行时间
                return taskId;
            });
        }

        // 获取任务执行结果
        for (int i = 0; i < 10; i++) {
            try {
                Future<Integer> future = completionService.take(); // 阻塞等待任务完成
                //Future<Integer> future = completionService.poll(); // 如果没有任务完成则返回 null
                int result = future.get(); // 获取任务执行结果
                System.out.println("Task " + result + " completed.");
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        // 关闭线程池
        executor.shutdown();
    }
}
